FUNCTION MODULE ZSTB_MODIFY_TABLE_BATCH
FUNCTION GROUP  ZSTB_FUNCTION_GROUP
DESCRIPTION     modify table in batch
PROCESSING TYPE : normal function module

IMPORT
PARAMETER       |TYPE_SPEC|ASSOCIATED_TYPE        |DEFAULT|OPTIONAL|PASS_VALUE|DESCRIPTION         
----------------|---------|-----------------------|-------|--------|----------|--------------------
TABLE_NAME      |TYPE     |TABLE_NAME             |       |NO      |YES       |Table Name          
FIELD_SEPARATOR |TYPE     |ZSTB_FIELD_SEP_TYPE    |','    |YES     |YES       |CSV field separator 
STRING_DELIMITER|TYPE     |ZSTB_STRING_DELIM_TYPE |'"'    |YES     |YES       |CSV string delimiter
ACTION          |TYPE     |ZSTB_MODIFY_ACTION_TYPE|'M'    |YES     |YES       |modify action       

TABLES
PARAMETER|TYPE_SPEC|ASSOCIATED_TYPE      |OPTIONAL|DESCRIPTION 
---------|---------|---------------------|--------|------------
HEADER   |LIKE     |ZSTB_FIELD_NAME_STRUC|NO      |fields names
FETCH    |LIKE     |ZSTB_FETCH_STRUC     |NO      |fetch data  

SOURCE CODE
...........
function zstb_modify_table_batch.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     VALUE(TABLE_NAME) TYPE  DD03L-TABNAME
*"     VALUE(FIELD_SEPARATOR) TYPE  ZSTB_FIELD_SEP_TYPE DEFAULT ','
*"     VALUE(STRING_DELIMITER) TYPE  ZSTB_STRING_DELIM_TYPE DEFAULT '"'
*"     VALUE(ACTION) TYPE  ZSTB_MODIFY_ACTION_TYPE DEFAULT 'M'
*"  TABLES
*"      HEADER STRUCTURE  ZSTB_FIELD_NAME_STRUC
*"      FETCH STRUCTURE  ZSTB_FETCH_STRUC
*"----------------------------------------------------------------------

data: dynamic_table type ref to data,
  dynamic_line type ref to data,
  last_line_number type i,
  next_line_number type i,
  last_line_part_number type i,
  next_line_part_number type i,
  csv_line type string,
  csv_table type table of string,
  fetch_line type zstb_fetch_struc,
  splitted_line type table of string,
  field_value type string,
  field_index type i,
  header_line type zstb_field_name_struc,
  line_length type i,
  offset_limit type i,
  current_offset type i,
  current_character type string, " WARNING : do not use a character type because space character will be ignored
  next_offset type i,
  next_character type string, " WARNING : do not use a character type because space character will be ignored
  inside_string_delim type i.
field-symbols: <dynamic_table> type table,
  <dynamic_line> type any,
 <dynamic_field> type any.

* get table structure from name
create data dynamic_table type table of (table_name).
assign dynamic_table->* to <dynamic_table>.

* get line structure from table
create data dynamic_line like line of <dynamic_table>.
assign dynamic_line->* to <dynamic_line>.

* reconstruct complete CSV lines
last_line_number = -1.
last_line_part_number = -1.
loop at fetch into fetch_line.
* keep track of line
  next_line_number = last_line_number + 1.
  next_line_part_number = last_line_part_number + 1.
* 0. initialization
  if last_line_number < 0 and last_line_part_number < 0.
    last_line_number = fetch_line-line_number.
    last_line_part_number = fetch_line-line_part_number.
    csv_line = fetch_line-line_data.
* 1. new partition (on same line)
  elseif last_line_number = fetch_line-line_number and next_line_part_number = fetch_line-line_part_number.
    last_line_part_number = fetch_line-line_part_number.
    concatenate csv_line fetch_line-line_data into csv_line.
* 2. new line
  elseif fetch_line-line_part_number = 0 and ( next_line_number = fetch_line-line_number or fetch_line-line_number = 0 ).
    last_line_number = fetch_line-line_number.
    last_line_part_number = fetch_line-line_part_number.
    append csv_line to csv_table.
    csv_line = fetch_line-line_data.
  endif.
endloop.
* append last line
append csv_line to csv_table.

* format each line from CSV to table structure
loop at csv_table into csv_line.

* split CSV line
* WARNING : SAP split command remove trailing spaces
  line_length = strlen( csv_line ).
  offset_limit = line_length - 1.
  current_offset = 0.
  next_offset = current_offset + 1.
  clear splitted_line.
  field_value = ''.
  inside_string_delim = 0.
* initialize characters
  current_character = ''.
  if current_offset <= offset_limit.
    current_character = csv_line+current_offset(1).
  endif.
  next_character = ''.
  if next_offset <= offset_limit.
    next_character = csv_line+next_offset(1).
  endif.
* split until the end of the line
  while current_character <> ''.
*   interpret current character
*   0. enter delimited field
    if inside_string_delim = 0 and current_character = string_delimiter.
      inside_string_delim = 1.
*     reset field
      field_value = ''.
*     jump 1 characters
      current_offset = current_offset + 1.
*   1. leave delimited field
    elseif inside_string_delim = 1 and current_character = string_delimiter and ( next_character = field_separator or next_character = '' ).
*     do not trigger last field without delimiter appending
      if next_character <> ''.
        inside_string_delim = 0.
      endif.
*     append field to line
      append field_value to splitted_line.
*     reset field
      field_value = ''.
*     jump 1 characters
      current_offset = current_offset + 2.
*   2. leave field without delimiter
    elseif inside_string_delim = 0 and current_character = field_separator.
*     append field to line
      append field_value to splitted_line.
*     reset field
      field_value = ''.
*     next characters
      current_offset = current_offset + 1.
*   3. string delimiter inside delimited field
    elseif inside_string_delim = 1 and current_character = string_delimiter and next_character = string_delimiter.
*     complete field
      concatenate field_value current_character into field_value.
*     next characters
      current_offset = current_offset + 2.
*   4. inside field (deliminited or not)
    else.
*     complete field
      concatenate field_value current_character into field_value.
*     next characters
      current_offset = current_offset + 1.
    endif.
*   incremente characters
    current_character = ''.
    if current_offset <= offset_limit.
      current_character = csv_line+current_offset(1).
    endif.
    next_character = ''.
    next_offset = current_offset + 1.
    if next_offset <= offset_limit.
      next_character = csv_line+next_offset(1).
    endif.
*   append last field without delimiter
    if inside_string_delim = 0 and current_character = ''.
      append field_value to splitted_line.
    endif.
  endwhile.

* create table line
  field_index = 1. " SAP array index start at 1
  loop at splitted_line into field_value.
*   insert field in line
    read table header into header_line index field_index.
    assign component header_line-name of structure <dynamic_line> to <dynamic_field>.
    <dynamic_field> = field_value.
*   next field
    field_index = field_index + 1.
  endloop.
* fill table
  append <dynamic_line> to <dynamic_table>.
endloop.

* apply changes
if action = 'M'.
  modify (table_name) from table <dynamic_table>.
elseif action = 'I'.
  insert (table_name) from table <dynamic_table>.
elseif action = 'U'.
  update (table_name) from table <dynamic_table>.
endif.

endfunction.